<!DOCTYPE html>
<html>
<head>
<title>HTML5 WebSocket / Geolocation Tracker</title>
<link rel="stylesheet" href="styles.css">
</head>
<body onload="loadDemo()">

<h1>HTML5 WebSocket / Geolocation Tracker</h1>

<div><strong>Geolocation</strong>: <p id="geoStatus">HTML5 Geolocation is <strong>not</strong> supported in your browser.</p></div>
<div><strong>WebSocket</strong>: <p id="socketStatus">HTML5 Web Sockets are <strong>not</strong> supported in your browser.</p></div>

<script>

    // reference to the Web Socket
    var socket;

    // a semi-unique random ID for this session
    var myId = Math.floor(100000*Math.random());

    // number of rows of data presently displayed
    var rowCount = 0;

    function updateSocketStatus(message) {
        document.getElementById("socketStatus").innerHTML = message;
    }

    function updateGeolocationStatus(message) {
        document.getElementById("geoStatus").innerHTML = message;
    }

    function handleLocationError(error) {
        switch(error.code)
        {
        case 0:
          updateGeolocationStatus("There was an error while retrieving your location: " + error.message);
          break;
        case 1:
          updateGeolocationStatus("The user prevented this page from retrieving a location.");
          break;
        case 2:
          updateGeolocationStatus("The browser was unable to determine your location: " + error.message);
          break;
        case 3:
          updateGeolocationStatus("The browser timed out before retrieving the location.");
          break;
        }
    }

    function loadDemo() {
        // test to make sure that Web Sockets are supported
        if (window.WebSocket) {

            // the location of our broadcast WebSocket server
            url = "ws://localhost:8080";
            socket = new WebSocket(url);
            socket.onopen = function() {
                updateSocketStatus("Connected to WebSocket tracker server");
            }
            socket.onmessage = function(e) {
                updateSocketStatus("Updated location from " + dataReturned(e.data));
            }
        }

        var geolocation;
        if(navigator.geolocation) {
            geolocation = navigator.geolocation;
            updateGeolocationStatus("HTML5 Geolocation is supported in your browser.");
        }

        // register for position updates using the Geolocation API
        geolocation.watchPosition(updateLocation,
                                  handleLocationError,
                                  {maximumAge:20000});
    }

    function updateLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var timestamp = position.timestamp;

        updateGeolocationStatus("Location updated at " + timestamp);

        // Send my location via WebSocket
        var toSend = JSON.stringify([myId, latitude, longitude]);
        sendMyLocation(toSend);
    }

    function sendMyLocation(newLocation) {
        if (socket) {
            socket.send(newLocation);
        }
    }

    function dataReturned(locationData) {
        // break the data into ID, latitude, and longitude
        var allData = JSON.parse(locationData);
        var incomingId   = allData[1];
        var incomingLat  = allData[2];
        var incomingLong = allData[3];

        // locate the HTML element for this ID
        // if one doesn't exist, create it
        var incomingRow = document.getElementById(incomingId);
        if (!incomingRow) {
            incomingRow = document.createElement('div');
            incomingRow.setAttribute('id', incomingId);

            incomingRow.userText = (incomingId == myId) ?
                                        'Me'            :
                                        'User ' + rowCount;

            rowCount++;

            document.body.appendChild(incomingRow);
        }

        // update the row text with the new values
        incomingRow.innerHTML = incomingRow.userText + " \\ Lat: " +
                                incomingLat + " \\ Lon: " +
                                incomingLong;

        return incomingRow.userText;
    }

</script>
</body>
</html>
